﻿namespace BizVal.Services
{
    using System.Linq;
    using BizVal.Contracts;
    using System;

    // ToDo: Implement other methods
    public class ValuationService
    {
        /// <summary>
        /// Calculates the value of a company using the Discounted Cashflow method.
        /// </summary>
        /// <param name="cashflow">Array of Free Cashflow values.</param>
        /// <param name="wacc">Array of WACC values.</param>
        /// <returns>The interval which the company value is whithin.</returns>
        public static Interval Cashflow(Interval[] cashflow, Interval[] wacc)
        {
            Interval total = new Interval();
            if (cashflow.Length > wacc.Length)
            {
                // ToDo: Exception.
            }
            else
            {
                for (int i = 0; i < cashflow.Length; i++)
                {
                    Interval currentCashflow = cashflow[i];
                    Interval totalWacc = new Interval()
                    {
                        LowerValue = 1,
                        HigherValue = 1
                    };
                    for (int j = 0; j <= i; j++)
                    {
                        totalWacc = totalWacc * ((1 + wacc[j]) ^ i);
                    }
                    total = total + (currentCashflow / totalWacc);
                }
            }
            return total;
        }


        /// <summary>
        /// Calculates the value of a company using the Mixed Analysis method.
        /// </summary>
        /// <param name="anr">The ANR.</param>
        /// <param name="revenueVector">Vector of expected revenues.</param>
        /// <param name="interestVector">Vector of expected interests types.</param>
        /// <returns>The interval which the company value is whithin.</returns>
        public static Interval MixedAnalysis(decimal anr, Interval[] revenueVector, Interval[] interestVector)
        {
            Interval value = new Interval();
            if (revenueVector.Length != interestVector.Length)
            {
                // ToDo: Exception
            }
            else
            {
                int periods = interestVector.Length;
                Interval sum = new Interval();
                Interval divisor = new Interval();
                for (int i = 0; i < periods; i++)
                {
                    var interest = ValuationService.InverseInterest(i, interestVector);
                    sum = sum + (interest * revenueVector[i]);
                    divisor = divisor + (interest * interestVector[i]);
                }
                sum = sum + anr;
                divisor = divisor + 1;
                value = sum / divisor;
            }
            return value;
        }

        private static Interval InverseInterest(int n, Interval[] interests)
        {
            Interval result = new Interval()
            {
                HigherValue = 1,
                LowerValue = 1
            };

            for (int i = 0; i <= n; i++)
            {
                result = result * (1 / (1 + interests[i]));
            }
            return result;
        }

    }
}
